//
//  WCGotoLineSheetController.m
//  WabbitCode
//
//  Created by William Towe on 10/20/08.
//  Copyright 2008 Revolution Software. All rights reserved.
//

#import "WCGotoLineSheetController.h"
#import "WCRulerView.h"
#import "NSString+WCExtensions.h"
#import "WCMacros.h"
#import "WCTextView.h"


@implementation WCGotoLineSheetController
#pragma mark *** Subclass Overrides ***

- (id)initWithWindow:(NSWindow *)window {
	if (!(self = [super initWithWindow:window]))
		return nil;
	
	_gotoToLineOrCharacter = NSUserDefaultsUnsignedIntegerForKey(kWCPrefsEditorGotoLineOrCharacter);
	
	return self;
}

- (void)setNilValueForKey:(NSString *)key {
	if ([key isEqualToString:@"lineOrCharacterNumber"]) {
		[self setLineOrCharacterNumber:_lineOrCharacterNumber];
	}
	else {
		[super setNilValueForKey:key];
	}
}
#pragma mark *** Public Methods ***

+ (void)presentGotoLineSheetForTextView:(WCTextView *)textView; {
	WCGotoLineSheetController *controller = [[[self class] alloc] initWithWindowNibName:@"WCGotoLineSheet"];
	[controller setTextView:textView];
	[controller setGotoLineOrCharacter:NSUserDefaultsUnsignedIntegerForKey(kWCPrefsEditorGotoLineOrCharacter)];
	
	switch ([controller gotoLineOrCharacter]) {
		case WCPEGotoLineOrCharacterGotoCharacter: {
			[controller setLineOrCharacterNumber:[[controller textView] selectedRange].location];
		}
			break;
		case WCPEGotoLineOrCharacterGotoLine: {
			[controller setLineOrCharacterNumber:[[[controller textView] rulerView] lineNumberForCharacterIndex:[[controller textView] selectedRange].location]+1];
		}
			break;
		default:
			break;
	}
	
	[NSApp beginSheet:[controller window] modalForWindow:[NSApp mainWindow] modalDelegate:controller didEndSelector:@selector(_gotoLineSheetDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}

@synthesize lineOrCharacterNumber = _lineOrCharacterNumber, gotoLineOrCharacter = _gotoToLineOrCharacter, textView = _textView;

- (BOOL)validateLineOrCharacterNumber:(id *)value error:(NSError **)error {
	if (*value == nil) {
		return YES;
	}
	else if ([*value isEqualToString:@"0"]) {
		*value = [NSNumber numberWithUnsignedInteger:1];
		return YES;
	}
	
	return [(NSString *)*value stringToNumber:value currentValue:[NSNumber numberWithUnsignedInteger:_lineOrCharacterNumber] error:error];
}

#pragma mark *** Private Methods ***
- (void)_gotoLineSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
	[self autorelease];
	if (returnCode == NSCancelButton)
		return;
	
	NSSetUserDefaultsUnsignedIntegerForKey([self gotoLineOrCharacter], kWCPrefsEditorGotoLineOrCharacter);
	
	switch ([self gotoLineOrCharacter]) {
		case WCPEGotoLineOrCharacterGotoCharacter: {
			NSString *string = [[self textView] string];
			if ([self lineOrCharacterNumber] >= [string length])
				[[self textView] setSelectedRange:NSMakeRange([string length], 0)];
			else
				[[self textView] setSelectedRange:NSMakeRange([self lineOrCharacterNumber], 0)];
			[[self textView] scrollRangeToVisible:[[self textView] selectedRange]];
		}
			break;
		case WCPEGotoLineOrCharacterGotoLine: {
			NSString *string = [[self textView] string];
			NSUInteger lines, index, length = [string length];
			for (index=0, lines=0; index<length; lines++) {
				if (lines == [self lineOrCharacterNumber]-1)
					break;
				index = NSMaxRange([string lineRangeForRange:NSMakeRange(index, 0)]);
			}
			if (index == length)
				[[self textView] setSelectedRange:NSMakeRange([string lineRangeForRange:NSMakeRange(index, 0)].location, 0)];
			else
				[[self textView] setSelectedRange:NSMakeRange(index, 0)];
			[[self textView] scrollRangeToVisible:[[self textView] selectedRange]];
		}
			break;
		default:
			break;
	}
}
@end
